home *** CD-ROM | disk | FTP | other *** search
- import java.awt.Color;
- import java.awt.Component;
- import java.awt.Dimension;
- import java.awt.Event;
- import java.awt.FontMetrics;
- import java.awt.Graphics;
- import java.awt.Image;
- import java.awt.Panel;
- import java.awt.image.ImageObserver;
-
- class GraphPanel extends Panel implements Runnable {
- Graph graph;
- int nnodes;
- Node[] nodes = new Node[100];
- int nedges;
- Edge[] edges = new Edge[200];
- Thread relaxer;
- boolean stress;
- boolean random;
- Node pick;
- boolean pickfixed;
- Image offscreen;
- Dimension offscreensize;
- Graphics offgraphics;
- final Color fixedColor;
- final Color selectColor;
- final Color edgeColor;
- final Color nodeColor;
- final Color stressColor;
- final Color arcColor1;
- final Color arcColor2;
- final Color arcColor3;
-
- GraphPanel(Graph graph) {
- this.fixedColor = Color.red;
- this.selectColor = Color.pink;
- this.edgeColor = Color.black;
- this.nodeColor = new Color(250, 220, 100);
- this.stressColor = Color.gray;
- this.arcColor1 = Color.black;
- this.arcColor2 = Color.pink;
- this.arcColor3 = Color.red;
- this.graph = graph;
- }
-
- int findNode(String lbl) {
- for(int i = 0; i < this.nnodes; ++i) {
- if (this.nodes[i].lbl.equals(lbl)) {
- return i;
- }
- }
-
- return this.addNode(lbl);
- }
-
- int addNode(String lbl) {
- Node n = new Node();
- n.x = (double)10.0F + (double)380.0F * Math.random();
- n.y = (double)10.0F + (double)380.0F * Math.random();
- n.lbl = lbl;
- this.nodes[this.nnodes] = n;
- return this.nnodes++;
- }
-
- void addEdge(String from, String to, int len) {
- Edge e = new Edge();
- e.from = this.findNode(from);
- e.to = this.findNode(to);
- e.len = (double)len;
- this.edges[this.nedges++] = e;
- }
-
- public void run() {
- while(true) {
- this.relax();
- if (this.random && Math.random() < 0.03) {
- Node n = this.nodes[(int)(Math.random() * (double)this.nnodes)];
- if (!n.fixed) {
- n.x += (double)100.0F * Math.random() - (double)50.0F;
- n.y += (double)100.0F * Math.random() - (double)50.0F;
- }
-
- this.graph.play(this.graph.getCodeBase(), "audio/drip.au");
- }
-
- try {
- Thread.sleep(100L);
- } catch (InterruptedException var2) {
- return;
- }
- }
- }
-
- synchronized void relax() {
- for(int i = 0; i < this.nedges; ++i) {
- Edge e = this.edges[i];
- double vx = this.nodes[e.to].x - this.nodes[e.from].x;
- double vy = this.nodes[e.to].y - this.nodes[e.from].y;
- double len = Math.sqrt(vx * vx + vy * vy);
- double f = (this.edges[i].len - len) / (len * (double)3.0F);
- double dx = f * vx;
- double dy = f * vy;
- Node var10000 = this.nodes[e.to];
- var10000.dx += dx;
- var10000 = this.nodes[e.to];
- var10000.dy += dy;
- var10000 = this.nodes[e.from];
- var10000.dx += -dx;
- var10000 = this.nodes[e.from];
- var10000.dy += -dy;
- }
-
- for(int i = 0; i < this.nnodes; ++i) {
- Node n1 = this.nodes[i];
- double dx = (double)0.0F;
- double dy = (double)0.0F;
-
- for(int j = 0; j < this.nnodes; ++j) {
- if (i != j) {
- Node n2 = this.nodes[j];
- double vx = n1.x - n2.x;
- double vy = n1.y - n2.y;
- double len = vx * vx + vy * vy;
- if (len == (double)0.0F) {
- dx += Math.random();
- dy += Math.random();
- } else if (len < (double)10000.0F) {
- dx += vx / len;
- dy += vy / len;
- }
- }
- }
-
- double dlen = dx * dx + dy * dy;
- if (dlen > (double)0.0F) {
- dlen = Math.sqrt(dlen) / (double)2.0F;
- n1.dx += dx / dlen;
- n1.dy += dy / dlen;
- }
- }
-
- Dimension d = ((Component)this).size();
-
- for(int i = 0; i < this.nnodes; ++i) {
- Node n = this.nodes[i];
- if (!n.fixed) {
- n.x += Math.max((double)-5.0F, Math.min((double)5.0F, n.dx));
- n.y += Math.max((double)-5.0F, Math.min((double)5.0F, n.dy));
- if (n.x < (double)0.0F) {
- n.x = (double)0.0F;
- } else if (n.x > (double)d.width) {
- n.x = (double)d.width;
- }
-
- if (n.y < (double)0.0F) {
- n.y = (double)0.0F;
- } else if (n.y > (double)d.height) {
- n.y = (double)d.height;
- }
- }
-
- n.dx /= (double)2.0F;
- n.dy /= (double)2.0F;
- }
-
- ((Component)this).repaint();
- }
-
- public void paintNode(Graphics g, Node n, FontMetrics fm) {
- int x = (int)n.x;
- int y = (int)n.y;
- g.setColor(n == this.pick ? this.selectColor : (n.fixed ? this.fixedColor : this.nodeColor));
- int w = fm.stringWidth(n.lbl) + 10;
- int h = fm.getHeight() + 4;
- g.fillRect(x - w / 2, y - h / 2, w, h);
- g.setColor(Color.black);
- g.drawRect(x - w / 2, y - h / 2, w - 1, h - 1);
- g.drawString(n.lbl, x - (w - 10) / 2, y - (h - 4) / 2 + fm.getAscent());
- }
-
- public synchronized void update(Graphics g) {
- Dimension d = ((Component)this).size();
- if (this.offscreen == null || d.width != this.offscreensize.width || d.height != this.offscreensize.height) {
- this.offscreen = ((Component)this).createImage(d.width, d.height);
- this.offscreensize = d;
- this.offgraphics = this.offscreen.getGraphics();
- this.offgraphics.setFont(((Component)this).getFont());
- }
-
- this.offgraphics.setColor(((Component)this).getBackground());
- this.offgraphics.fillRect(0, 0, d.width, d.height);
-
- for(int i = 0; i < this.nedges; ++i) {
- Edge e = this.edges[i];
- int x1 = (int)this.nodes[e.from].x;
- int y1 = (int)this.nodes[e.from].y;
- int x2 = (int)this.nodes[e.to].x;
- int y2 = (int)this.nodes[e.to].y;
- int len = (int)Math.abs(Math.sqrt((double)((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2))) - e.len);
- this.offgraphics.setColor(len < 10 ? this.arcColor1 : (len < 20 ? this.arcColor2 : this.arcColor3));
- this.offgraphics.drawLine(x1, y1, x2, y2);
- if (this.stress) {
- String lbl = String.valueOf(len);
- this.offgraphics.setColor(this.stressColor);
- this.offgraphics.drawString(lbl, x1 + (x2 - x1) / 2, y1 + (y2 - y1) / 2);
- this.offgraphics.setColor(this.edgeColor);
- }
- }
-
- FontMetrics fm = this.offgraphics.getFontMetrics();
-
- for(int i = 0; i < this.nnodes; ++i) {
- this.paintNode(this.offgraphics, this.nodes[i], fm);
- }
-
- g.drawImage(this.offscreen, 0, 0, (ImageObserver)null);
- }
-
- public synchronized boolean mouseDown(Event evt, int x, int y) {
- double bestdist = Double.MAX_VALUE;
-
- for(int i = 0; i < this.nnodes; ++i) {
- Node n = this.nodes[i];
- double dist = (n.x - (double)x) * (n.x - (double)x) + (n.y - (double)y) * (n.y - (double)y);
- if (dist < bestdist) {
- this.pick = n;
- bestdist = dist;
- }
- }
-
- this.pickfixed = this.pick.fixed;
- this.pick.fixed = true;
- this.pick.x = (double)x;
- this.pick.y = (double)y;
- ((Component)this).repaint();
- return true;
- }
-
- public synchronized boolean mouseDrag(Event evt, int x, int y) {
- this.pick.x = (double)x;
- this.pick.y = (double)y;
- ((Component)this).repaint();
- return true;
- }
-
- public synchronized boolean mouseUp(Event evt, int x, int y) {
- this.pick.x = (double)x;
- this.pick.y = (double)y;
- this.pick.fixed = this.pickfixed;
- this.pick = null;
- ((Component)this).repaint();
- return true;
- }
-
- public void start() {
- this.relaxer = new Thread(this);
- this.relaxer.start();
- }
-
- public void stop() {
- this.relaxer.stop();
- }
- }
-